home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-01-24 | 52.2 KB | 1,184 lines |
- Chapter 8
-
-
-
-
-
- Video Page Management
-
- 150 Fastgraph User's Guide
-
-
- Overview
-
- The amount of memory required to store one full screen of information is
- called a video page. This chapter will discuss video pages in detail, along
- with the Fastgraph routines you can use to manage video pages.
-
-
- Physical Pages and Virtual Pages
-
- Pages that use the memory that resides on the video adapter are called
- physical pages or true pages. The number of physical pages available depends
- on the video mode and the amount of memory resident on the user's video
- adapter. All video modes have at least one physical page. In certain video
- modes, Fastgraph can allocate available random-access memory (RAM) and treat
- this memory as a video page. Pages that use standard RAM in this sense are
- called virtual pages. From a programmer's perspective, virtual pages are
- essentially identical to physical pages.
-
- The following table shows the number of physical pages in each video
- mode. It also indicates whether or not specific video modes support virtual
- pages.
-
- Mode Page Size Physical Virtual
- Number Description in Bytes Pages Pages
-
- 0 40 column color text 2,000 8 no
- 1 40 column color text 2,000 8 no
- 2 80 column color text 4,000 4 no
- 3 80 column color text 4,000 4 no
- 4 320x200x4 CGA graphics 16,000 1 yes
- 5 320x200x4 CGA graphics 16,000 1 yes
- 6 640x200x2 CGA graphics 16,000 1 yes
- 7 80 column monochrome text 4,000 1 yes
- 9 320x200x16 Tandy graphics 32,000 1 yes
- 11 720x348 Hercules graphics 31,320 2 yes
- 12 320x200 Hercules graphics 31,320 2 yes
- 13 320x200x16 EGA graphics 32,000 8 no
- 14 640x200x16 EGA graphics 64,000 4 no
- 15 640x350 EGA mono graphics 56,000 2 no
- 16 640x350x16 EGA graphics 112,000 2 no
- 17 640x480x2 MCGA/VGA graphics 38,400 1+ no
- 18 640x480x16 VGA graphics 153,600 1+ no
- 19 320x200x256 MCGA graphics 64,000 1 yes
- 20 320x200x256 XVGA graphics 64,000 4 no
- 21 320x400x256 XVGA graphics 128,000 2 no
- 22 320x240x256 XVGA graphics 76,800 3+ no
- 23 320x480x256 XVGA graphics 153,600 1+ no
- 24 640x400x256 SVGA graphics 256,000 4 no
- 25 640x480x256 SVGA graphics 307,200 2 no
- 26 800x600x256 SVGA graphics 480,000 2 no
- 27 1024x768x256 SVGA graphics 786,432 1+ no
- 28 800x600x16 SVGA graphics 240,000 4 no
- 29 1024x768x16 SVGA graphics 393,216 2 no
-
- This table assumes the video adapter has 256K of video memory installed for
- EGA and VGA modes, and 1MB of video memory for SVGA modes. For adapters with
- Chapter 8: Video Page Management 151
-
-
- less video memory, the number of physical pages is reduced proportionately.
- In other words, a 64K EGA has two video pages available instead of eight in
- mode 13. Similarly, a 512K SVGA has one page instead of two in modes 25 and
- 26, and wouldn't support mode 27. The next table summarizes the number of
- video pages available in SVGA graphics modes for video cards with 256K, 512K,
- 768K, and 1MB of video memory installed.
-
- Mode Number of pages with...
- Number Resolution 256K 512K 768K 1MB
-
- 24 640x400x256 1+ 2 3 4
- 25 640x480x256 0 1+ 1+ 2
- 26 800x600x256 0 1+ 1+ 2
- 27 1024x768x256 0 0 1 1+
- 28 800x600x16 1+ 2 3 4
- 29 1024x768x16 0 1+ 1+ 2
-
- In the preceding two tables, note that the number of physical pages in
- some video modes is followed by a plus symbol. In these modes, there is an
- additional partial video page available. For modes 17, 18, and 23, there is
- one full page (page 0) plus one partial page of 320 pixel rows (page 1). For
- mode 22, there are three full physical pages (numbered 0 to 2) plus one
- partial page of 80 pixel rows (page 3). For mode 27, there is one full page
- (page 0) plus one partial page of 256 pixel rows (page 1) on a 1MB SVGA card.
- You can safely use the partial pages as long as you don't reference pixel
- rows beyond its last available row. However, you cannot make a partial video
- page the visual page.
-
- In SVGA graphics modes (modes 24 to 29), video pages must begin on 256K
- boundaries to maintain compatibility between different SVGA chipsets. This
- results in unused video memory at the end of a page. For example, pages in
- mode 26 require 480,000 bytes of video memory. On a 1MB SVGA card, the two
- pages will begin at 0 and 524,288 (512K). Thus there are 44,288 (524,288
- minus 480,000) unused video memory bytes at the end of each page. With 800
- pixels (and hence 800 bytes) per screen row, this means each page has an
- extra 55 pixel rows per page. The actual page size is therefore 800 by 654,
- with the first 600 rows being displayed.
-
- Physical pages are numbered starting at zero. For example, there are
- four physical video pages available in mode 3, and they are numbered 0 to 3.
- Virtual pages are numbered n to 63, where n is the number of physical pages
- in that mode. For example, there are two physical pages (numbered 0 and 1)
- and 62 virtual pages (numbered 2 to 63) in mode 11. Note only modes 4
- through 12 and mode 19 offer virtual pages, and the amount of conventional
- memory in the user's system usually limits the number of virtual pages
- available (this is especially true in mode 19 because of the large page
- size).
-
-
- Pages With Special Meanings
-
- There are three video pages that have special meanings to Fastgraph.
- The visual page, as one might guess, is the video page currently visible on
- the user's display. The active page is the video page to which Fastgraph
- writes text or graphics information. The hidden page is meaningful only to a
- few Fastgraph routines and will be discussed specifically within the context
- 152 Fastgraph User's Guide
-
-
- of those routines. The fg_setmode routine sets all three of these pages to
- page 0, and it does not matter if these pages are physical or virtual.
-
- One of the most useful features of multiple video pages (either physical
- or virtual) is the ability to build a text or graphics image off screen (that
- is, on some video page besides the visual page). Then, once the image is
- ready, we can either transfer it to the visual page, or make the page on
- which the image resides the visual page. This feature is especially useful
- in animation, for it displays an image instantaneously instead of visibly
- updating the screen while producing the image.
-
-
- Some Simple Examples
-
- In this section, we will present six variations of a simple program that
- uses four video pages. The program fills each video page with a rectangle
- and then displays text containing the video page number in the center of each
- page. The first two examples run in a specific text or graphics video mode
- and only use physical pages. The next two examples also run in a specific
- text or graphics video mode, but they also use virtual pages. The final two
- examples are more general and run in several video modes. You could of
- course write a program that essentially does the same thing as the examples
- in this section without using multiple video pages. However, to use
- Fastgraph's image display and animation routines effectively, you must first
- understand the concept of video pages.
-
- Before proceeding, we must introduce the Fastgraph routines fg_setpage
- and fg_setvpage. The fg_setpage routine defines the active video page, which
- causes Fastgraph to put subsequent text and graphics output on that page.
- The fg_setvpage routine defines the visual video page displayed on the
- screen. Both routines take a single integer argument between 0 and 63 that
- specifies the video page number. It does not matter if the referenced video
- page is a physical page or a virtual page. As mentioned earlier, fg_setmode
- makes page 0 the active and visual video page.
-
- Example 8-1 uses four video pages (numbered 0 to 3) in the 40-column
- color text mode (mode 1). The program first calls fg_testmode to check the
- availability of the requested video mode when used with four video pages. If
- it is available, the program calls fg_setmode to establish that video mode.
- The first for loop fills each of the four pages with different color
- rectangles and then displays black text containing the video page number in
- the center of each page. It does this by calling fg_setpage to define the
- active video page, fg_setcolor and fg_rect to draw the colored rectangles,
- and finally fg_setattr, fg_locate, and fg_text to display the text. The
- program must call fg_locate inside the loop because each video page has its
- own text cursor position. The second for loop successively makes each video
- page the visual page; the page remains displayed until you press a key.
- After displaying all four video pages, the program restores the original
- video mode and screen attributes before returning to DOS.
-
- Example 8-1.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
- Chapter 8: Video Page Management 153
-
-
- #define PAGES 4
-
- void main()
- {
- int color;
- int old_mode;
- int page;
- char string[8];
-
- if (fg_testmode(1,PAGES) == 0) {
- printf("This program requires color.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(1);
-
- for (page = 0; page < PAGES; page++) {
- fg_setpage(page);
- color = page + 1;
- fg_setcolor(color);
- fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
- fg_setattr(0,color,0);
- fg_locate(12,17);
- sprintf(string,"page %d",page);
- fg_text(string,6);
- }
-
- for (page = 0; page < PAGES; page++) {
- fg_setvpage(page);
- fg_waitkey();
- }
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
- Example 8-2 is similar to example 8-1, but it uses the 320 by 200 EGA
- graphics mode (mode 13) instead of a text mode. Note the only real
- difference between this program and the text mode version is the use of
- fg_setcolor instead of fg_setattr to make the text appear in black.
-
- Example 8-2.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- #define PAGES 4
-
- void main()
- {
- int color;
- int old_mode;
- int page;
- 154 Fastgraph User's Guide
-
-
- char string[8];
-
- if (fg_testmode(13,PAGES) == 0) {
- printf("This program requires a ");
- printf("320 x 200 EGA graphics mode.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(13);
-
- for (page = 0; page < PAGES; page++) {
- fg_setpage(page);
- color = page + 1;
- fg_setcolor(color);
- fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
- fg_setcolor(0);
- fg_locate(12,17);
- sprintf(string,"page %d",page);
- fg_text(string,6);
- }
-
- for (page = 0; page < PAGES; page++) {
- fg_setvpage(page);
- fg_waitkey();
- }
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
-
- Virtual video pages are created with Fastgraph's fg_allocate routine.
- The fg_allocate routine reserves conventional random-access memory (RAM)
- which Fastgraph then treats as a video page. The amount of memory required
- depends on the current video mode. The fg_allocate routine takes a single
- integer argument that specifies the page number by which the virtual page
- will be referenced. This value must be between 0 and 63.
-
- If you try to create a virtual page with a page number already assigned
- to a physical page, fg_allocate does nothing. For example, in the Hercules
- graphics modes (modes 11 and 12) there are two physical pages numbered 0 and
- 1. Virtual pages in the Hercules graphics modes must thus have page numbers
- between 2 and 63. If you tell fg_allocate to create a Hercules virtual page
- numbered 0 or 1, it does nothing because those video pages are physical
- pages. Similarly, if you use the fg_allocate routine in a video mode that
- does not support virtual video pages, it simply returns without doing
- anything.
-
- A possible problem with fg_allocate can occur when there is not enough
- memory available for creating a virtual page in the current video mode. The
- fg_allocate routine returns as its function value a status code indicating
- whether or not it was successful. The possible values of the status code
- are:
-
- value meaning
- Chapter 8: Video Page Management 155
-
- 0 virtual page created
- 1 specified page number is a physical page
- 7 virtual page created, but memory control blocks were destroyed
- 8 insufficient memory to create the virtual page
-
- If you use the fg_testmode or fg_bestmode routines to check if the required
- number of video pages are available when using the requested video mode, you
- should not need to monitor the status code returned by the fg_allocate
- routine.
-
- The fg_freepage routine releases the memory for a virtual page created
- with fg_allocate. It requires a single integer argument that identifies the
- virtual page number to release. This value must be between 0 and 63. If you
- try to release a physical video page, or release a virtual page that was
- never created, fg_freepage does nothing. It is a good idea to use
- fg_freepage to release all virtual video pages before a program returns
- control to DOS, or just before a program selects a new video mode.
-
- Example 8-3 is also similar to example 8-1, but it uses the monochrome
- text mode (mode 7). Because the monochrome text mode only has one physical
- video page, we must use virtual video pages for page numbers 1, 2, and 3.
- Note how the fg_allocate and fg_freepage routines are used to create and
- release the virtual video pages in this example.
-
- Example 8-3.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- #define PAGES 4
-
- void main()
- {
- int old_mode;
- int page;
- char string[8];
-
- if (fg_testmode(7,PAGES) == 0) {
- printf("This program requires monochrome.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(7);
- fg_cursor(0);
-
- for (page = 0; page < PAGES; page++) {
- fg_allocate(page);
- fg_setpage(page);
- fg_setcolor(7);
- fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
- fg_setattr(0,7,0);
- fg_locate(12,37);
- sprintf(string,"page %d",page);
- fg_text(string,6);
- 156 Fastgraph User's Guide
-
-
- }
-
- for (page = 0; page < PAGES; page++) {
- fg_setvpage(page);
- fg_waitkey();
- fg_freepage(page);
- }
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
- Example 8-4 is similar to example 8-3, but it uses the standard Hercules
- graphics mode (mode 11) instead of the monochrome text mode. Because the
- Hercules graphics modes have two physical video pages, we must use virtual
- video pages for page numbers 2 and 3. Note the only real difference between
- this program and the text mode version is the use of fg_setcolor instead of
- fg_setattr to make the text appear in black.
-
- Example 8-4.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- #define PAGES 4
-
- void main()
- {
- int old_mode;
- int page;
- char string[8];
-
- if (fg_testmode(11,PAGES) == 0) {
- printf("This program requires Hercules ");
- printf("monochrome graphics.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(11);
-
- for (page = 0; page < PAGES; page++) {
- fg_allocate(page);
- fg_setpage(page);
- fg_setcolor(7);
- fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
- fg_setcolor(0);
- fg_locate(12,37);
- sprintf(string,"page %d",page);
- fg_text(string,6);
- }
-
- for (page = 0; page < PAGES; page++) {
- fg_setvpage(page);
- Chapter 8: Video Page Management 157
-
-
- fg_waitkey();
- fg_freepage(page);
- }
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
- Example 8-5 is a generalized version of examples 8-1 and 8-3 that runs
- in any 80-column text video mode. To simplify the program, each video page
- is filled with rectangles of the same color. Note that fg_allocate and
- fg_freepage are used to manage the virtual video pages in case fg_bestmode
- selects the monochrome text mode (mode 7). If fg_bestmode selects one of the
- 80-column color text modes (which have four physical video pages),
- fg_allocate and fg_freepage will simply return without doing anything.
-
- Example 8-5.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- #define PAGES 4
-
- void main()
- {
- int old_mode, new_mode;
- int page;
- char string[8];
-
- new_mode = fg_bestmode(80,25,PAGES);
- if (new_mode < 0) {
- printf("This program requires ");
- printf("an 80-column display.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(new_mode);
- fg_cursor(0);
-
- for (page = 0; page < PAGES; page++) {
- fg_allocate(page);
- fg_setpage(page);
- fg_setcolor(7);
- fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
- fg_setattr(0,7,0);
- fg_locate(12,37);
- sprintf(string,"page %d",page);
- fg_text(string,6);
- }
-
- for (page = 0; page < PAGES; page++) {
- fg_setvpage(page);
- fg_waitkey();
- 158 Fastgraph User's Guide
-
-
- fg_freepage(page);
- }
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
- Example 8-6 is a generalized version of examples 8-2 and 8-4 that runs
- in any 320 by 200 graphics video mode. To simplify the program, each video
- page is filled with rectangles of the same color. As in example 8-5,
- fg_allocate and fg_freepage are used to manage the virtual video pages in
- case fg_bestmode selects a video mode with fewer than four physical video
- pages. Note the only real difference between this program and the text mode
- version is the use of fg_setcolor instead of fg_setattr to make the text
- appear in black.
-
- Example 8-6.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- #define PAGES 4
-
- void main()
- {
- int old_mode, new_mode;
- int page;
- char string[8];
-
- new_mode = fg_bestmode(320,200,PAGES);
- if (new_mode < 0) {
- printf("This program requires a ");
- printf("320 x 200 graphics mode.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(new_mode);
-
- for (page = 0; page < PAGES; page++) {
- fg_allocate(page);
- fg_setpage(page);
- fg_setcolor(15);
- fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
- fg_setcolor(0);
- fg_locate(12,17);
- sprintf(string,"page %d",page);
- fg_text(string,6);
- }
-
- for (page = 0; page < PAGES; page++) {
- fg_setvpage(page);
- fg_waitkey();
- fg_freepage(page);
- Chapter 8: Video Page Management 159
-
-
- }
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
-
- Text Cursors
-
- As mentioned in the previous chapter, Fastgraph draws hardware
- characters at the position defined by the text cursor. Like the graphics
- cursor, the text cursor is not a cursor in the true sense, but is simply a
- pair of character space (row,column) coordinates with a special meaning. The
- first 8 video pages (that is, pages 0 through 7) each have their own text
- cursor. Each subsequent group of 8 video pages (pages 8 through 15, pages 16
- to 23, and so forth) respectively share the same text cursor positions as the
- first 8 pages. This means the fg_locate routine will update one of 8
- different text cursors depending on the active video page. Similarly, the
- fg_where routine returns the text cursor position for the active page. The
- fg_setmode routine sets all 8 text cursor positions to the character space
- coordinates (0,0).
-
- Example 8-7 demonstrates the use of different text cursors in an 80-
- column color text mode (mode 3). The program first displays the text "Page "
- on video page 0 (the visible page) and waits for a keystroke. It then makes
- page 1 the active video page, changes the text cursor location for that page,
- and displays the text "Page 1" on video page 1. Next, it appends the
- character "0" to the text originally displayed on page 0. Note it is not
- necessary to restore the text cursor position for page 0 because it is
- unaffected by changing the text cursor for page 1. After waiting for another
- keystroke, the program makes video page 1 the visual page and then waits for
- yet another keystroke before returning to DOS.
-
- Example 8-7.
-
- #include <fastgraf.h>
- void main(void);
-
- void main()
- {
- int old_mode;
-
- old_mode = fg_getmode();
- fg_setmode(3);
- fg_cursor(0);
- fg_setattr(10,0,0);
-
- fg_locate(1,0);
- fg_text("Page ",5);
- fg_waitkey();
-
- fg_setpage(1);
- fg_locate(23,0);
- fg_text("Page 1",6);
-
- fg_setpage(0);
- 160 Fastgraph User's Guide
-
-
- fg_text("0",1);
- fg_waitkey();
-
- fg_setvpage(1);
- fg_waitkey();
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
-
- Obtaining Video Page Information
-
- Fastgraph includes two routines, fg_getpage and fg_getvpage, that
- respectively return the current active or visual video page number. Each
- routine returns the video page number as its function value, and neither
- routine requires any arguments.
-
- The fg_getaddr routine is sometimes useful when using virtual pages. It
- returns as its function value the segment address for the start of the active
- video page. It does not require any arguments. Although fg_getaddr is more
- useful when using virtual video pages, it works equally well when using
- physical video pages.
-
- Example 8-8 illustrates the use of the fg_getpage, fg_getvpage, and
- fg_getaddr routines in the standard CGA color graphics mode (mode 4). This
- video mode offers only one physical page, so the program uses fg_allocate to
- create a virtual video page (page 1). After creating the virtual page, the
- program makes it the active video page; page 0 remains the visual video page.
- The fg_getpage routine then returns the active page number (1), followed by a
- call to fg_getvpage to return the visual page number (0). Next, the program
- uses fg_getaddr to return the segment address for video pages 0 and 1.
- Finally, it restores the original video mode and screen attributes, displays
- the returned values, and returns to DOS.
-
- Example 8-8.
-
- #include <fastgraf.h>
- #include <stdio.h>
- void main(void);
-
- void main()
- {
- int old_mode;
- int active, visual;
- int page0, page1;
-
- old_mode = fg_getmode();
- fg_setmode(4);
- fg_allocate(1);
- fg_setpage(1);
-
- active = fg_getpage();
- visual = fg_getvpage();
-
- fg_setpage(0);
- Chapter 8: Video Page Management 161
-
-
- page0 = fg_getaddr();
- fg_setpage(1);
- page1 = fg_getaddr();
-
- fg_freepage(1);
- fg_setmode(old_mode);
- fg_reset();
-
- printf("Active page is %d.\n",active);
- printf("Visual page is %d.\n",visual);
- printf("Page 0 address is %4X\n",page0);
- printf("Page 1 address is %4X\n",page1);
- }
-
-
- Considerations for Virtual Pages
-
- If you're using Power C, QuickBASIC, Visual Basic, Borland Pascal, or
- Turbo Pascal and need to create virtual pages, you must reduce the size of
- the far heap. Normally, these compilers allocate all remaining memory for
- the heap, which means fg_allocate will not be able to allocate memory for the
- virtual page.
- In QuickBASIC and Visual Basic programs, the SETMEM function reduces the
- size of the far heap. The BASIC versions of the Fastgraph example programs
- include the statement
-
- SetMemStatus& = SETMEM(-n)
-
- before calling FGallocate. This reduces the size of the far heap by n bytes.
- For a given video mode, the actual reduction needed is the number of virtual
- pages multiplied by the page size in that mode. Page sizes are listed at the
- beginning of this chapter, or you can use fg_pagesize to determine the page
- size for the current video mode.
-
- In Borland Pascal and Turbo Pascal, the $M compiler directive defines
- the maximum heap size in bytes. The Pascal versions of the Fastgraph example
- programs include the statement
-
- {$M 16384,0,16384}
-
- at the beginning of the examples that call fg_allocate. The third value in
- this list defines the maximum heap size at 16K bytes. This is suitable for
- most applications, but if your program uses the New or GetMem procedures to
- create dynamic variables that require more heap space, you'll need to
- increase the size beyond 16K.
-
- The far heap size for Power C programs is defined at link time. You
- must override the default heap size by including the option [,,16K] on the
- PCL command when you link a Power C program that uses fg_allocate. The value
- 16K is suitable for most applications, but if your program calls the
- farcalloc or farmalloc functions (or the calloc or malloc functions when
- using the large memory model), you may need to increase the far heap size
- beyond 16K.
-
- When you are using virtual pages, you should avoid using the fg_setvpage
- routine in sections of the program that require fast screen updates or
- 162 Fastgraph User's Guide
-
- animation sequences. This is because the PC and PS/2 video BIOS are only
- capable of displaying physical pages. To compensate for this restriction,
- Fastgraph exchanges the contents of a physical page with the requested
- virtual page. In other words, if page 1 is a virtual page and you make it
- the visual page, Fastgraph will exchange the contents of page 1 with whatever
- page was previously the visual page. This does not mean Fastgraph's page
- numbers change because Fastgraph also maintains an internal table containing
- video page addresses and exchanges the two corresponding table entries. As
- before, you would make page 1 the active video page if you wanted to write
- something to the visual page.
-
- About the only other potential problem when using virtual pages is what
- happens when you try to write to a non-existent video page (for example, if
- you write to virtual video page 1 before creating it with fg_allocate). In
- this case, Fastgraph simply redirects the video output to the visual page.
-
-
- Logical Pages
-
- In addition to physical and virtual video pages, Fastgraph offers
- another class of video pages, called logical pages. You can create logical
- pages in any video mode. They can exist in conventional memory, expanded
- memory (EMS), or extended memory (XMS). However, they are not as versatile
- as physical or virtual pages because the only operations you can perform with
- logical pages are:
-
- Copy an entire physical or virtual page to a logical page
- Copy an entire logical page to a physical or virtual page
- Copy an entire logical page to another logical page
-
- Three Fastgraph routines -- fg_alloccms, fg_allocems, and fg_allocxms --
- create logical pages in conventional memory, expanded memory, and extended
- memory, respectively. All three routines have a single integer argument that
- specifies the page number by which the logical page will be referenced. The
- page number must be between 1 and 63 and must not reference a physical or
- virtual page. Their return value is 0 if the logical page is created, and
- negative otherwise (refer to the descriptions of these routines in the
- Fastgraph Reference Manual for a complete list of return values). As with
- virtual pages, use the fg_freepage function to release a logical page.
-
- Before you can create logical pages in expanded or extended memory, you
- must initialize these resources for use with Fastgraph. The fg_initems
- routine initializes expanded memory. To use expanded memory, you must have
- an Expanded Memory Manager (EMM) that conforms to the Lotus/Intel/Microsoft
- Expanded Memory Specification (LIM-EMS) version 3.2 or later. On 80386 and
- 80486 systems, the EMM386.EXE device driver supplied with DOS 5.0 can be used
- to treat some or all of extended memory as expanded memory. The fg_initxms
- routine initializes extended memory for use with Fastgraph. To use extended
- memory, you must have an XMS driver that conforms to the
- Lotus/Intel/Microsoft/AST eXtended Memory Specification version 2.0 or later,
- such as HIMEM.SYS. XMS drivers require an 80286, 80386, or 80486 system.
- The fg_initems and fg_initxms routines have no arguments. Their return value
- is 0 if successful, and -1 if the required driver and resources are not
- present.
-
- Example 8-9 illustrates the use of logical pages in a 320 by 200 color
- graphics mode. The program first tries to create a logical page in extended
- Chapter 8: Video Page Management 163
-
- memory by calling fg_initxms and fg_allocxms. If the initialization or page
- creation fails, it then tries to create the page in expanded memory with
- fg_initems and fg_allocems. Should that fail, the program calls fg_alloccms
- to try to create the page in conventional memory. If it can't create the
- logical page at all, the program displays an error message and exits.
-
- Once the logical page is created, example 8-9 displays the word "test"
- in the middle of the visual page (page 0) and then uses fg_copypage to
- transfer the visual page contents to the logical page (page 8). Because this
- program runs in one of several different graphics modes, we must use a
- logical page number greater than any possible physical page number. We chose
- page 8 because mode 13 has physical pages numbered 0 through 7, and no mode
- has higher-numbered physical pages. After waiting for a keystroke, the
- program erases the visual page, waits for another keystroke, and copies the
- logical page contents back to the visual page. It then releases the logical
- page and exits.
-
- Example 8-9.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- void main()
- {
- int new_mode, old_mode;
- int status;
-
- new_mode = fg_bestmode(320,200,1);
- if (new_mode < 0 || new_mode == 12) {
- printf("This program requires a 320 ");
- printf("x 200 color graphics mode.\n");
- exit(1);
- }
- old_mode = fg_getmode();
- fg_setmode(new_mode);
-
- status = fg_initxms();
- if (status == 0) status = fg_allocxms(8);
- if (status < 0) {
- status = fg_initems();
- if (status == 0) status = fg_allocems(8);
- }
- if (status < 0) status = fg_alloccms(8);
-
- if (status < 0) {
- fg_setmode(old_mode);
- fg_reset();
- printf("Unable to create logical page.\n");
- exit(1);
- }
-
- fg_setcolor(7);
- fg_rect(0,319,0,199);
- fg_setcolor(9);
- fg_locate(12,18);
- 164 Fastgraph User's Guide
-
-
- fg_text("test",4);
- fg_waitkey();
-
- fg_copypage(0,8);
- fg_erase();
- fg_waitkey();
-
- fg_copypage(8,0);
- fg_waitkey();
-
- fg_freepage(8);
- fg_setmode(old_mode);
- fg_reset();
- }
-
- As mentioned before, the only function you can perform with logical
- pages is copying one video page to another. The fg_copypage routine provides
- the only way to do this for logical pages. See Chapter 11 for more
- information about fg_copypage.
-
-
- Video Page Resizing
-
- Resizing is the process of changing the dimensions of a video page. It
- is available only in the native EGA graphics modes (modes 13 to 16), native
- VGA graphics modes (17 and 18), extended VGA modes (20 to 23), and SVGA modes
- (24 to 29). Resizing does not change the screen resolution, but instead
- increases the video page size so that only part of the page is visible. For
- now, we'll just introduce resizing with a simple example, but in Chapter 13
- we'll see its real power when we perform smooth panning.
-
- The Fastgraph routine fg_resize changes the dimensions of a video page.
- Its two integer arguments define the page width and page height, both in
- pixels. Example 8-10 runs in the 320 by 200 EGA graphics mode (mode 13).
- After establishing the video mode, it displays the word "resize" starting in
- column 38 of row 0. Because the characters extend beyond the last column of
- the row, they wrap to the next row. The program continues displaying this
- until you press a key. Then, it clears the screen and calls fg_resize to
- make the page size 640 by 200 pixels. Again the program displays the word
- "resize" starting in column 38 of row 0, but this time it does not wrap to
- the next row. This is because the resizing doubled the page width, which
- increased the number of character cells per row from 40 to 80. The
- characters that formerly wrapped to the next row now continue on an off-
- screen portion of the same row.
-
- Example 8-10.
-
- #include <fastgraf.h>
- #include <stdio.h>
- #include <stdlib.h>
- void main(void);
-
- void main()
- {
- int old_mode;
-
- Chapter 8: Video Page Management 165
-
-
- if (fg_testmode(13,1) == 0) {
- printf("This program requires a 320 ");
- printf("x 200 EGA graphics mode.\n");
- exit(1);
- }
-
- old_mode = fg_getmode();
- fg_setmode(13);
-
- fg_setcolor(9);
- fg_locate(0,38);
- fg_text("resize",6);
- fg_waitkey();
-
- fg_erase();
- fg_resize(640,200);
- fg_setcolor(10);
- fg_locate(0,38);
- fg_text("resize",6);
- fg_waitkey();
-
- fg_setmode(old_mode);
- fg_reset();
- }
-
-
- The size of a video page is constrained only by the amount of video
- memory available. Increasing the video page size reduces the number of
- physical pages available proportionally. In mode 13, for example, increasing
- the page size from 320 by 200 to 640 by 400 reduces the number of video pages
- from 8 to 2. When you call fg_resize, the visual page must be page 0. If
- you have created any logical video pages, you must release them with
- fg_freepage before calling fg_resize, and then create them again afterward.
- If you have initialized the mouse (with fg_mouseini), joysticks (with
- fg_initjoy), expanded memory (with fg_initems), or extended memory (with
- fg_initxms), you should re-initialize these resources after calling
- fg_resize. Most mouse drivers expect a fixed video page width, so the mouse
- cursor may become distorted after resizing video pages. When you call
- fg_resize, Fastgraph sets the clipping region to the new page limits. The
- fg_setmode routine re-establishes the dimensions of a video page to the
- default screen resolution for the selected video mode.
-
- Depending on the dimensions passed to fg_resize, you may end up with a
- partial video page. Again, suppose we're using mode 13 and have changed the
- page size to 960 by 400 (this is six times the default page size). The
- original pages 0 to 5 now comprise page 0, and original pages 6 and 7 now
- comprise page 1. However, there is not enough video memory left on page 1
- for a full 960 by 400 page. In this case, the number of pixel rows available
- on page 1 would be one-third the full page size, or 133 rows. This is
- because the total storage required by original pages 6 and 7 is one-third the
- total required for original pages 0 through 5.
- 166 Fastgraph User's Guide
-
-
-
- Preserving Video Page Contents Across Mode Switches
-
- Sometimes a graphics program may temporarily need to switch to another
- video mode. An example of this might be a graphical user interface (GUI)
- menuing system that includes "shell to DOS" as one of its options. When the
- user selects this option, the program must revert to a text video mode so the
- user will see the familiar DOS prompt when the shell executes. On leaving
- the DOS shell, the program returns to a graphics mode and should ideally
- restore the screen to what it was originally.
-
- When you establish a video mode with fg_setmode, Fastgraph clears all
- physical video pages and initializes its internal page tables as if no
- virtual or logical pages have been created. While it's not possible to
- preserve physical page contents across video mode switches, you can use
- Fastgraph's fg_getentry and fg_setentry routines to save virtual or logical
- page contents. The trick, so to speak, is using fg_getentry to save the
- virtual or logical page address and type before switching video modes. Then,
- when you return to the same video mode, you can use fg_setentry to restore
- the internal page tables to their previous state. This effectively makes the
- virtual or logical page accessible again.
-
- Example 8-11 illustrates this process. This program runs in video mode
- 18, the 640 by 480 16-color VGA graphics mode. After establishing this video
- mode, the program calls fg_alloccms to create a logical page in conventional
- memory (we chose page 2 because this is the first page number available for
- logical pages in mode 18). Next, it calls fg_getentry to save the address
- and type of the logical page just created. The first argument to fg_getentry
- specifies the page number; the next two arguments receive the page address
- and type. Page type codes used by fg_getentry and fg_setentry are as
- follows:
-
- 0 = unallocated page
- 1 = physical page
- 2 = virtual page
- 3 = logical page in expanded memory (EMS)
- 4 = logical page in extended memory (XMS)
- 5 = logical page in conventional memory
-
- After this setup work, example 8-11 fills the screen with light blue
- pixels, draws a white box around the edge, and then waits for a keystroke.
- Before switching back to the original video mode (assumed to be mode 3), the
- program uses fg_copypage to copy the visual page contents to the logical
- page. This is necessary because we can only save virtual or logical page
- contents across video mode changes, not physical pages. In mode 3, the
- program prompts for a keystroke before returning to mode 18.
-
- Now we're ready to restore the previous contents of the visual page.
- Because the example program did not release the logical page, the memory is
- still allocated; Fastgraph just cannot access it. To solve this, the program
- calls fg_setentry to restore Fastgraph's internal page table entries for page
- 2 to what they were previously. Note how we use the same page address and
- type values in the call to fg_setentry that were returned earlier by
- fg_getentry. Now that the logical page (page 2) is once again accessible,
- the program can use fg_copypage to copy its contents back to the visual page.
- With that explanation behind us, here is example 8-11.
- Chapter 8: Video Page Management 167
-
-
- Example 8-11.
-
- #include <fastgraf.h>
- void main(void);
-
- void main()
- {
- int old_mode;
- int page_addr, page_type;
-
- old_mode = fg_getmode();
- fg_setmode(18);
- fg_alloccms(2);
- fg_getentry(2,&page_addr,&page_type);
-
- fg_setcolor(9);
- fg_fillpage();
- fg_setcolor(15);
- fg_box(0,639,0,479);
- fg_waitkey();
-
- fg_copypage(0,2);
- fg_setmode(old_mode);
- fg_cursor(0);
- fg_setcolor(15);
- fg_text("Press any key.",14);
- fg_waitkey();
-
- fg_setmode(18);
- fg_setentry(2,page_addr,page_type);
- fg_copypage(2,0);
- fg_waitkey();
-
- fg_freepage(2);
- fg_setmode(old_mode);
- fg_reset();
- }
-
-
- To keep the example as simple as possible, it does not test for
- availability of video modes, nor does it check if the logical page creation
- was successful. In a real application, of course, omitting these checks is
- not recommended.
-
-
- Controlling Page Allocation
-
- When Fastgraph creates virtual or logical pages in conventional memory
- with fg_allocate or fg_alloccms, it uses the DOS allocate memory service
- (function 48 hex of interrupt 21 hex). Some compilers allocate all or part
- of available conventional memory to a data structure called the heap or far
- heap. Memory allocation functions such as malloc handle their requests
- through an associated heap manager instead of through DOS services. If the
- heap manager controls all available memory, the DOS allocate memory service
- is essentially disabled because there will be no memory available to satisfy
- allocation requests. If the heap manager controls some but not all available
- 168 Fastgraph User's Guide
-
- memory, a conflict may arise between the heap manager and the DOS allocate
- memory service.
-
- To solve this problem, you can use the compiler's allocate far memory
- function to reserve memory for the virtual or logical page and then make the
- page known to Fastgraph with fg_setentry. The easiest way to determine the
- amount of memory to allocate is through the fg_pagesize function, which
- returns the page size in bytes (as a long integer) for the current video
- mode. To release the page, use fg_setentry with a page type of zero to mark
- the page as unallocated before actually freeing the memory. Pages created
- this way are not initially cleared because the allocated memory block
- contents are undefined. We recommend using fg_erase to set the page contents
- to the background color.
-
- Example 8-12 shows how to create a virtual page using these techniques
- instead of fg_allocate. It uses the farmalloc and farfree functions from the
- C run-time library for Borland compilers (the analogous Microsoft functions
- are _fmalloc and _ffree). Example 8-12 uses fg_pagesize and the Borland run-
- time library function farmalloc to create a virtual page in the 320 by 200
- VGA/MCGA 256-color graphics mode. After allocating the memory, the program
- calls fg_setentry, passing it the page number (1), the segment portion of the
- memory block address (using the FP_SEG macro from the run-time library), and
- the code for a virtual page (2). Once the virtual page is set up, the
- program writes some text on the virtual page and then uses fg_copypage to
- display the virtual page contents on the visual page. Finally, it releases
- the page by calling fg_setentry (so Fastgraph knows the virtual page is gone)
- and the farfree run-time library function (to actually free the memory). The
- call to fg_setentry is not really needed in this instance because no further
- references are made to page 1.
-
- Example 8-12.
-
- #include <fastgraf.h>
- #include <dos.h>
- #ifdef __TURBOC__
- #include <alloc.h>
- #else
- #include <malloc.h>
- #define farfree(p) _ffree(p)
- #define farmalloc(n) _fmalloc(n)
- #endif
- void main(void);
-
- void main()
- {
- int old_mode;
- unsigned page_addr;
- char far *buffer;
-
- old_mode = fg_getmode();
- fg_setmode(19);
- buffer = farmalloc(fg_pagesize()+16);
- page_addr = FP_SEG(buffer) + (FP_OFF(buffer)+15)/16;
- fg_setentry(1,page_addr,2);
-
- fg_setpage(1);
- fg_erase();
- Chapter 8: Video Page Management 169
-
-
- fg_setcolor(9);
- fg_text("This is page 1.",15);
- fg_waitkey();
-
- fg_copypage(1,0);
- fg_setentry(1,0,0);
- fg_waitkey();
-
- farfree(buffer);
- fg_setmode(old_mode);
- fg_reset();
- }
-
-
-
- Summary of Video Page Management Routines
-
- This section summarizes the functional descriptions of the Fastgraph
- routines presented in this chapter. More detailed information about these
- routines, including their arguments and return values, may be found in the
- Fastgraph Reference Manual.
-
- FG_ALLOCATE creates a virtual video page. The amount of memory required
- depends on the current video mode. This routine has no effect if it
- references a physical or logical video page.
-
- FG_ALLOCEMS creates a logical page in expanded memory (EMS). The amount
- of memory required depends on the current video mode and video buffer
- dimensions. This routine has no effect if it references a physical or
- virtual video page.
-
- FG_ALLOCXMS creates a logical page in extended memory (XMS). The amount
- of memory required depends on the current video mode and video buffer
- dimensions. This routine has no effect if it references a physical or
- virtual video page.
-
- FG_COPYPAGE transfers the contents of one video page to another. The
- pages may be physical, virtual, or logical video pages. If both pages are
- logical pages, they must exist in the same type of memory.
-
- FG_FREEPAGE releases a virtual or logical video page created with the
- fg_allocate, fg_alloccms, fg_allocems, or fg_allocxms routines. This routine
- has no effect if it references a physical video page, or a virtual page that
- was never created.
-
- FG_GETADDR returns the segment address of the active video page.
-
- FG_GETENTRY retrieves the type and address of a physical, virtual, or
- logical video page. This routine is useful for saving virtual or logical
- page contents across video mode changes.
-
- FG_GETPAGE returns the active video page number.
-
- FG_GETVPAGE returns the visual video page number.
-
- FG_INITEMS initializes expanded memory for use with Fastgraph.
- 170 Fastgraph User's Guide
-
-
- FG_INITXMS initializes extended memory for use with Fastgraph.
-
- FG_PAGESIZE returns the video page size in bytes for the current video
- mode.
-
- FG_RESIZE changes the dimensions of a video page in EGA and VGA graphics
- modes.
-
- FG_SETENTRY specifies the type and address of a physical, virtual, or
- logical video page. For logical pages, it further specifies if the page
- resides in conventional, expanded, or extended memory. This routine is
- useful for saving virtual or logical page contents across video mode changes,
- or for manual creation of virtual and logical pages.
-
- FG_SETPAGE establishes the active video page. It may be a physical or
- virtual page.
-
- FG_SETVPAGE establishes the visual video page. It may be a physical or
- virtual page.